package com.m4f.web.controller;

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Calendar;
import java.util.Locale;
import java.util.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestParam;
import com.m4f.business.model.BestPracticeType;
import com.m4f.business.model.Company;
import com.m4f.business.model.Vote;
import com.m4f.business.service.AppConfigurationService;
import com.m4f.business.service.VoteService;
import com.m4f.business.service.CompanyService;
import com.m4f.business.service.TagsCloudService;
import com.m4f.business.service.helper.TagsCloud;
import java.io.IOException;
import java.security.Principal;
import javax.cache.CacheException;
import javax.validation.Valid;
import com.m4f.business.service.exception.DuplicatedVoteException;
import com.m4f.business.service.exception.VotesLimitExceedException;
import com.m4f.web.bind.form.VoteForm;

@Controller
@RequestMapping("/")
public class HomeController extends BaseController {

	private static final Logger LOGGER = Logger.getLogger(HomeController.class.getName());
	
	@Autowired
	private AppConfigurationService appConfigurationService;
	@Autowired
	private CompanyService companyService;
	@Autowired
	private VoteService voteService;
	@Autowired
	private TagsCloudService cloudService;
	
	
	public HomeController() throws CacheException {
		super();
	}
	
	@RequestMapping(method=RequestMethod.GET)
	public String getView(Principal currentUser, Model model)
			throws IOException, ClassNotFoundException {
		if(currentUser!=null) {
			LOGGER.info("++User: " + currentUser.getName());
			Company company = 
				this.companyService.getCompanyByParticipant(currentUser.getName());
			model.addAttribute("company", company);
		}
		Long stage = this.appConfigurationService.getGlobalConfiguration().getStage();
		
		switch(stage.intValue()) {
			case 2:
					List<Company> jurySelectedCompanies = this.getJurySelectedCompanies();				
					model.addAttribute("preselectedCompanies", jurySelectedCompanies);
					model.addAttribute("maxVotes", this.appConfigurationService.getGlobalConfiguration().getMaxVotes());
					model.addAttribute("voteForm", new VoteForm());
					break;
			case 3: 
					List<Company> finalistCompanies = this.getFinalistCompanies();
					model.addAttribute("finalistCompanies", finalistCompanies);
			default:
					List<Company> allCompanies = this.getAllCompanies();
					model.addAttribute("companies", allCompanies);
					model.addAttribute("cloud", this.getCloud());
					model.addAttribute("bestPracticeTypes", this.getBestPracticeTypes());
		}
		return "home_" + stage;
	}
	
	
	
	@RequestMapping(value="/vote", method=RequestMethod.POST)
	public String vote(@Valid VoteForm voteForm, BindingResult result, Model model) {
		if (result.hasErrors()) {
			return "redirect:/";
		}
		int futureVotes = voteForm.getCompanies()==null?0:voteForm.getCompanies().size();
		if(futureVotes==0) return "votenook";
		if(futureVotes<this.appConfigurationService.getGlobalConfiguration().getMaxVotes()) return "votenook";
		Integer votes = this.voteService.countVotes(voteForm.getVoter());
		if(votes>0) return "votenook";
		if(votes>this.appConfigurationService.getGlobalConfiguration().getMaxVotes()) return "votenook";
		for(Long company : voteForm.getCompanies()) {
			Vote vote = new Vote();
			vote.setCompanyId(company);
			vote.setEmail(voteForm.getVoter());
			vote.setReleaseDate(Calendar.getInstance(new Locale("es")).getTime());
			this.voteService.addVote(vote);
		}
		LOGGER.info("+++++++++++++++++ VOTO INSERTADOS +++++++++++++++++++");
		return "voteok";
	}
	
	
	
	@RequestMapping(value="/system-version", method=RequestMethod.GET)
	public String getSystemVersion(Model model) {
		String message = "The system's version is 1.0-alpha";
		model.addAttribute("message", message);
		return "common/thanks";
	}
	
	private List<Company> getAllCompanies() {
		return this.companyService.getCompanies(true);
	}
	

	private List<Company> getFinalistCompanies() {
		return this.companyService.getFinalistCompanies();
	}
	
	private List<Company> getJurySelectedCompanies() {
		List<Company> preselectedCompanies = null;
		if(this.cache.containsKey("preselectedCompanies")) {
			preselectedCompanies = (List<Company>)this.cache.get(PRESELECTED_COMPANIES_KEY);
		} else{
			preselectedCompanies = this.companyService.getPreselectedCompanies();
			this.cache.put(PRESELECTED_COMPANIES_KEY, preselectedCompanies);
		}		
		return preselectedCompanies;
	}
	
	private TagsCloud getCloud() 
		throws IOException, ClassNotFoundException {
		return this.cloudService.getTagsCloud();
	}
	
	
	private List<BestPracticeType> getBestPracticeTypes() {
		return this.appConfigurationService.getGlobalConfiguration().getBestPracticeTypes();
	}
	
	
}